package com.atguigu.daijia.dispatch.xxl.client;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.dispatch.xxl.config.XxlJobClientConfig;
import com.atguigu.daijia.model.entity.dispatch.XxlJobInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Objects;

/**
 * @author 山顶洞人郑某
 * @className XxlJobClient.java
 * @date 2024 09 11
 */
@Component
@Slf4j
public class XxlJobClient {
    @Autowired
    private XxlJobClientConfig xxlJobClientConfig;
    @Autowired
    private RestTemplate restTemplate;

    //添加并启动任务
    public Long addAndStart(String executorHandler, String param, String corn, String desc) {
        String url = xxlJobClientConfig.getAddAndStartUrl(); //获取访问地址
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setJobGroup(xxlJobClientConfig.getJobGroupId());
        xxlJobInfo.setJobDesc(desc);
        xxlJobInfo.setAuthor("qy");
        xxlJobInfo.setScheduleType("CRON");
        xxlJobInfo.setScheduleConf(corn);
        xxlJobInfo.setGlueType("BEAN");
        xxlJobInfo.setExecutorHandler(executorHandler);
        xxlJobInfo.setExecutorParam(param);
        xxlJobInfo.setExecutorRouteStrategy("FIRST");
        xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
        xxlJobInfo.setMisfireStrategy("FIRE_ONCE_NOW");
        xxlJobInfo.setExecutorTimeout(0);
        xxlJobInfo.setExecutorFailRetryCount(0);


        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxlJobInfo, headers);

        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);//发送请求获取结果

        HttpStatusCode code = response.getStatusCode();


        if (code.value()!=200){
            log.info("添加任务失败,{}", Objects.requireNonNull(response.getBody()).toJSONString());
            throw new GuiguException(ResultCodeEnum.SERVICE_ERROR);
        }
        JSONObject jsonObject = response.getBody();
        Long jobId = jsonObject.getLong("content");
        return jobId;
    }


    //删除任务
    public Boolean removeJob(Long jobId) {
        String url = xxlJobClientConfig.getRemoveUrl();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setJobGroup(xxlJobClientConfig.getJobGroupId());
        HttpEntity<XxlJobInfo> entity = new HttpEntity<>(xxlJobInfo,headers);
        ResponseEntity<JSONObject> response = restTemplate.exchange(url, HttpMethod.DELETE, entity, JSONObject.class);
        return response.getStatusCode().value() == 200;
    }

    //添加任务
    public Long addTask(String executorHandler, String param, String corn, String desc) {
        String url = xxlJobClientConfig.getAddUrl(); //获取访问地址
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setJobGroup(xxlJobClientConfig.getJobGroupId());
        xxlJobInfo.setJobDesc(desc);
        xxlJobInfo.setAuthor("qy");
        xxlJobInfo.setScheduleType("CRON");
        xxlJobInfo.setScheduleConf(corn);
        xxlJobInfo.setGlueType("BEAN");
        xxlJobInfo.setExecutorHandler(executorHandler);
        xxlJobInfo.setExecutorParam(param);
        xxlJobInfo.setExecutorRouteStrategy("FIRST");
        xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
        xxlJobInfo.setMisfireStrategy("FIRE_ONCE_NOW");
        xxlJobInfo.setExecutorTimeout(0);
        xxlJobInfo.setExecutorFailRetryCount(0);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<XxlJobInfo> entity = new HttpEntity<>(xxlJobInfo,headers);

        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, entity, JSONObject.class);

        if (response.getStatusCode().value() == 200) {
            return response.getBody().getLong("content");
        }
        else {
            log.info("远程调用添加任务失败:{}", Objects.requireNonNull(response.getBody()).toJSONString());
            throw new GuiguException(ResultCodeEnum.FAIL);
        }
    }

    public Boolean startJob(Long jobId) {
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setId(jobId.intValue());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxlJobInfo, headers);

        String url = xxlJobClientConfig.getStartJobUrl();
        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
        if(response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
            log.info("启动xxl执行任务成功:{},返回信息:{}", jobId, response.getBody().toJSONString());
            return true;
        }
        log.info("启动xxl执行任务失败:{},返回信息:{}", jobId, response.getBody().toJSONString());
        throw new GuiguException(ResultCodeEnum.DATA_ERROR);
    }

    public Boolean stopJob(Long jobId) {
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setId(jobId.intValue());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxlJobInfo, headers);

        String url = xxlJobClientConfig.getStopJobUrl();
        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
        if(response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
            log.info("停止xxl执行任务成功:{},返回信息:{}", jobId, response.getBody().toJSONString());
            return true;
        }
        log.info("停止xxl执行任务失败:{},返回信息:{}", jobId, response.getBody().toJSONString());
        throw new GuiguException(ResultCodeEnum.DATA_ERROR);
    }

}

/**
 * @RequestMapping("/addJob")
 *        @ResponseBody
 *    @PermissionLimit(limit = false)
 * 	public ReturnT<String> addJobInfo(@RequestBody XxlJobInfo jobInfo) {
 * 		return xxlJobService.add(jobInfo);
 *    }
 *
 * 	//删除任务
 *    @RequestMapping("/removeJob")
 *    @ResponseBody
 *    @PermissionLimit(limit = false)
 * 	public ReturnT<String> removeJob(@RequestBody XxlJobInfo jobInfo) {
 * 		return xxlJobService.remove(jobInfo.getId());
 *    }
 *
 * 	//修改任务
 *    @RequestMapping("/updateJob")
 *    @ResponseBody
 *    @PermissionLimit(limit = false)
 * 	public ReturnT<String> updateJob(@RequestBody XxlJobInfo jobInfo) {
 * 		return xxlJobService.update(jobInfo);
 *    }
 *
 * 	//停止任务
 *    @RequestMapping("/stopJob")
 *    @ResponseBody
 *    @PermissionLimit(limit = false)
 * 	public ReturnT<String> pauseJob(@RequestBody XxlJobInfo jobInfo) {
 * 		return xxlJobService.stop(jobInfo.getId());
 *    }
 *
 * 	//启动任务
 *    @RequestMapping("/startJob")
 *    @ResponseBody
 *    @PermissionLimit(limit = false)
 * 	public ReturnT<String> startJob(@RequestBody XxlJobInfo jobInfo) {
 * 		return xxlJobService.start(jobInfo.getId());
 *    }
 *
 * 	//添加并启动任务
 *    @RequestMapping("/addAndStartJob")
 *    @ResponseBody
 *    @PermissionLimit(limit = false)
 * 	public ReturnT<String> addAndStartJob(@RequestBody XxlJobInfo jobInfo) {
 * 		ReturnT<String> result = xxlJobService.add(jobInfo);
 *
 * 		String content = result.getContent();
 * 		int id = Integer.parseInt(content);
 * 		xxlJobService.start(id);
 *
 * 		//立即执行一次
 * 		JobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, jobInfo.getExecutorParam(), "");
 * 		return result;
 *    }
 */
